#include "checksum.h"
unsigned short get_ipv4_checksum(unsigned short *ptr, int len) {  
    register long sum;  
    unsigned short oddbyte;  
    register short answer;  
    sum = 0;  
    while (len > 1) {  
        sum += *ptr++;  
        len -= 2;  
    }  
    if (len == 1) {  
        oddbyte = 0;  
        *((unsigned char*)&oddbyte) = *(unsigned char*)ptr;  
        sum += oddbyte;  
    }  
    sum = (sum >> 16) + (sum & 0xffff);  
    sum += (sum >> 16);  
    answer = (short)~sum;  
    return answer;  
} 
unsigned short get_ipv4_tcp_checksum(unsigned short *addr, int len, in_addr_t saddr, in_addr_t daddr) {  
    register long sum = 0;  
    unsigned short answer;  
    unsigned short *w = addr;  
    unsigned short oddbyte;  
    sum += saddr;  
    sum += daddr;  
    sum += htons(IPPROTO_TCP);
    sum += htons(len);
    while(len > 1) {  
        sum += *w++;  
        len -= 2;  
    }   
    if(len == 1) {  
        oddbyte = 0;  
        *((unsigned char*)&oddbyte) = *(unsigned char*)w;  
        sum += oddbyte;  
    }   
    sum = (sum >> 16) + (sum & 0xffff);  
    sum += (sum >> 16);  
    answer = ~sum;   
    return answer;  
} 
unsigned short get_ipv6_tcp_checksum(unsigned short *addr, int len, struct in6_addr src_ip, struct in6_addr  dst_ip) {  
    register long sum = 0;  
    unsigned short answer;  
    unsigned short *w = addr;  
    unsigned short oddbyte;  
    unsigned short *src_ip_ptr = (unsigned short *)&src_ip;
    unsigned short *dst_ip_ptr = (unsigned short *)&dst_ip;
    for(int i = 0;i < 8;i++){
        sum += *(src_ip_ptr+i);
        sum += *(dst_ip_ptr+i);
    } 
    sum += htons(IPPROTO_TCP);
    sum += htons(len);
    while(len > 1) {  
        sum += *w++;  
        len -= 2;  
    }   
    if(len == 1) {  
        oddbyte = 0;  
        *((unsigned char*)&oddbyte) = *(unsigned char*)w;  
        sum += oddbyte;  
    }   
    sum = (sum >> 16) + (sum & 0xffff);  
    sum += (sum >> 16);  
    answer = ~sum;   
    return answer;  
}  
